#include "game.h"
#include "common-call.h"
#include "msg.h"
#include <cassert>
#include <intrin.h>

static LONG_PTR ORIGIN_WNDPROC = NULL;

int64 new_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg) {
  case WM_SEND_CALL: {
    UINT64 *args = (UINT64 *)lParam;
    return common(args);
  } break;
  case WM_GET_GS: {
    return __readgsqword(0x58);
  } break;
  default:
    break;
  }

  return (CallWindowProc((WNDPROC)ORIGIN_WNDPROC, hwnd, uMsg, wParam, lParam));
}

int64 Game::send_call(uint64 *args) {
  return SendMessage(window_, WM_SEND_CALL, NULL, (LPARAM)args);
}

void Game::hook_main_thread() {
  if (ORIGIN_WNDPROC)
    return;
  ORIGIN_WNDPROC =
      SetWindowLongPtr(window_, GWLP_WNDPROC, (LONG_PTR)new_wndproc);
}
void Game::unhook_main_thread() {
  if (ORIGIN_WNDPROC == NULL)
    return;
  SetWindowLongPtr(window_, GWLP_WNDPROC, (LONG_PTR)ORIGIN_WNDPROC);
  ORIGIN_WNDPROC = NULL;
}

Game::Game(uint32 pid, HWND window, uint64 base)
    : pid_{pid}, window_{window}, base_{base} {}

Game::~Game() {}

uint64 Game::core_base() { return Game::core_base_; }
void Game::set_core_base(uint64 core_base) { Game::core_base_ = core_base; }
uint64 Game::core_base_{0};
